package com.tc.groovy


/**
 * Created by cai.tian on 2018/1/18.
 */
class ComponentDelegate {
    final Object component;
    ComponentDelegate(Object component) {
        this.component = component;
    }
    /**
     * 没有找到调用的方法是调用
     * @param name
     * @param args
     */
    void methodMissing(String name, def args) {
        NestingType nestingType = PropertyUtil.nestingType(component, name);
        if (nestingType == NestingType.NA) {
            return;
        }
        String subComponentName
        Class clazz
        Closure closure
        (subComponentName, clazz, closure) = analyzeArgs(args)
        if (clazz != null) {
            Object subComponent = clazz.newInstance()
            if (subComponentName && subComponent.hasProperty(name)) {
                subComponent.name = subComponentName;
            }
            if (closure) {
                ComponentDelegate subDelegate = new ComponentDelegate(subComponent)
                closure.delegate = subDelegate
                closure.resolveStrategy = Closure.DELEGATE_FIRST
                closure()
            }
            PropertyUtil.attach(nestingType, component, subComponent, name)
        } else {
        }
    }
    /**
     * 类set 属性时候 调用
     * @param name
     * @param value
     */
    void propertyMissing(String name, def value) {
        NestingType nestingType = PropertyUtil.nestingType(component, name);
        if (nestingType == NestingType.NA) {
            return;
        }
        PropertyUtil.attach(nestingType, component, value, name)
    }

    Class parseClassArgument(arg) {
        if (arg instanceof Class) {
            return arg
        } else if (arg instanceof String) {
            return Class.forName(arg)
        } else {
            return null;
        }
    }
    String parseNameArgument(arg) {
        if (arg instanceof String) {
            return arg
        } else {
            return null;
        }
    }

    def analyzeArgs(Object[] args) {
        String name;
        Class clazz;
        Closure closure;
        if (args.size() > 3) {
            return [name, clazz, closure]
        }
        if (args[-1] instanceof Closure) {
            closure = args[-1]
            args -= args[-1]
        }
        if (args.size() == 1) {
            clazz = parseClassArgument(args[0])
        }
        if (args.size() == 2) {
            name = parseNameArgument(args[0])
            clazz = parseClassArgument(args[1])
        }
        return [name, clazz, closure]
    }

}
